package com.ev.framework.utils;

import com.ev.common.vo.CustomizedColumnVO;
import javassist.*;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.StringMemberValue;

import java.io.IOException;
import java.util.List;
import java.util.UUID;

/**
 * 类描述: [动态生成EasyPoi解析实体类]</br>
 * 初始作者:  AirOrangeWorkSpace </br>
 * 创建日期: 2020/5/15 16:28<br/>
 * 开始版本: 1.0.0<br/>
 * =================================================<br/>
 * 修改记录：<br/>
 * 修改作者 日期 修改内容<br/>
 * ================================================<br/>
*/
public class EasyPoiDynamicGenerationClassUtil {
    public static final String CLASS_NAME_PREFIX = "com.ev.common.vo.EasyPoiExcelVO@";
    public static final String ANNOTATION_PACKAGE_NAME = "cn.afterturn.easypoi.excel.annotation.Excel";
    public static final String STRING_PACKAGE_NAME = "java.lang.String";
    /**
     * 方法描述: [获取动态生成EasyPoi实体VO]</br>
     * 初始作者:  AirOrangeWorkSpace </br>
     * 创建日期: 2020/5/15 16:38<br/>
     * 开始版本: 1.0.0<br/>
     * =================================================<br/>
     * 修改记录：<br/>
     * 修改作者 日期 修改内容<br/>
     * ================================================<br/>
     * @param  list:获取用户自定义表头
     * @Return : 动态生成的EasyPoi实体类
    */
    public static Class<?> generatePrototypeClass(List<CustomizedColumnVO> list) throws NotFoundException, CannotCompileException, IOException {

        String className = CLASS_NAME_PREFIX + UUID.randomUUID().toString();

        ClassPool pool = ClassPool.getDefault();
        CtClass clazz = pool.makeClass(className);
        ClassFile ccFile = clazz.getClassFile();
        ConstPool constpool = ccFile.getConstPool();
        //添加fields
        addExpressField(pool, clazz, constpool,list);

        return clazz.toClass();
    }

    private static void addExpressField(ClassPool pool, CtClass clazz, ConstPool constpool,List<CustomizedColumnVO> list) throws CannotCompileException, NotFoundException {
        // 将数据库查出动态附上property 属性
        for (CustomizedColumnVO customizedColumnVO : list) {
            addFieldAndAnnotation(pool, clazz, constpool, customizedColumnVO.getName(), customizedColumnVO.getProperty());
        }
    }


    private static void addFieldAndAnnotation(ClassPool pool, CtClass clazz, ConstPool constpool, String titleName, String fieldName) throws NotFoundException, CannotCompileException {

        //生成field
        CtField field = new CtField(pool.get(STRING_PACKAGE_NAME), fieldName, clazz);
        field.setModifiers(Modifier.PUBLIC);

        //添加easypoi的注解
        AnnotationsAttribute fieldAttr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
        Annotation annotation = new Annotation(ANNOTATION_PACKAGE_NAME, constpool);
        annotation.addMemberValue("name", new StringMemberValue(titleName, constpool));
        fieldAttr.addAnnotation(annotation);
        field.getFieldInfo().addAttribute(fieldAttr);

        //生成get,set方法
        clazz.addMethod(CtNewMethod.getter("get" + upperFirstLatter(fieldName), field));
        clazz.addMethod(CtNewMethod.setter("set" + upperFirstLatter(fieldName), field));

        clazz.addField(field);
    }

    private static String upperFirstLatter(String letter) {
        return letter.substring(0, 1).toUpperCase() + letter.substring(1);
    }


}
